using Godot;
using System;


namespace Box {
	public partial class CodeEditControl : Control
	{
		[Signal]
		public delegate void onApplyEventHandler();
		[Signal]
		public delegate void onCanceEventHandler();

		public readonly string[] keywords = {
				"abstract","as","base","bool","break","byte","case","catch","char","checked","class","const","continue",
				"decimal","default","delegate","do","double","else","enum","event","explicit","extern","false","finally",
				"fixed","float","for","foreach","goto","if","implicit","in","int","interface","internal","is","lock",
				"long","namespace","new","null","object","operator","out","override","params","private","protected","public",
				"readonly","ref","sbyte","sealed","short","sizeof","stackalloc","static","string","struct","switch","this",
				"throw","true","try","typeof","uint","ulong","unchecked","unsafe","ushort","using","virtual","void","volatile","while",
				"add","and","alias","ascending","args","async","await","by","descending","dynamic","equals","from","get",
				"global","group","init","into","join","let","nint","not","notnull","uint","on","or","orderby","partial","record","remove",
				"select","set","unmanaged","value","var","when","where","where","with","yield",
		};

		[Export]
		public Color KeywordColor = Colors.White;
		public CodeEdit CodeEdit;
		public Button ApplyButton;
		public Button CancelButton;

		FileAccess File;
        String OldString;
        Action<string> ApplyCallback;

		public bool IsPreviewMode {
			set {
				if(value) {
					ApplyButton.Visible = false;
					CancelButton.Visible = false;
					CodeEdit.Editable = false;
				}
			}
		}

		public string Text {
			get {
				return CodeEdit.Text;
			}

			set {
				CodeEdit.Text = value;
			}
		}

		public override void _Ready()
		{
			CodeEdit = GetNode<CodeEdit>("VBoxContainer/CodeEdit");
			ApplyButton = GetNode<Button>("VBoxContainer/HBoxContainer/ApplyButton");
			CancelButton = GetNode<Button>("VBoxContainer/HBoxContainer/CancelButton");
			CodeHighlighter code_highlighter = CodeEdit.SyntaxHighlighter as CodeHighlighter;

			foreach(string keyword in keywords) {
				code_highlighter.AddKeywordColor(keyword,KeywordColor);
			}

			if(!code_highlighter.HasColorRegion("//")) {
				code_highlighter.AddColorRegion("//","",new Color(0xd6d6d6ff),true);
				code_highlighter.AddColorRegion("/*","*/",new Color(0xd6d6d6ff),false);
			}

			ApplyButton.ButtonDown += _onApply;
			CancelButton.ButtonDown += _onCancel;
		}

		public void Open(Action<string> apply_callback) {
            ApplyCallback = apply_callback;
        }

        public void Open(string file_name) {
            File = FileAccess.Open(file_name,FileAccess.ModeFlags.ReadWrite);
            OldString = File.GetAsText();
			Text = OldString;
            ApplyCallback = null;
        }


		public override void _Input(InputEvent @event)
        {
            if(@event is InputEventKey) {
                if(Input.IsActionPressed("ui_save")) {
                    _onApply();
                }
            }
        }

		public void _onApply() {
            if(File != null) {
                if(Text != OldString) {
                    File.Seek(0);
                    File.StoreString(Text);
                }
            } else {
                if(ApplyCallback != null) {
                    ApplyCallback(Text);
                }
            }
        }

        public void _onCancel() {
            if(File != null) {
				if(File.IsOpen()) {
					File.Close();
				}
                File = null;
            }
            ApplyCallback = null;
        }
	}
}
